Skip to content

fix(runners): declarations budget po-2024 12->42 Go (VM WSL 40 Go) - #17322

Merged
myia-ai-01 merged 1 commit into
mainfrom
fix/runner-budget-declaration-40gb
Sep 22, 2026
Merged

myia-ai-01 merged 1 commit into
mainfrom
fix/runner-budget-declaration-40gb

Conversation

@jsboige

@jsboige jsboige commented Sep 21, 2026

Copy link
Copy Markdown
Owner

Grain: LIGHT/tooling — lane myia-po-2024:CoursIA — prev: MED/guard #17308

Ce que fait cette PR

Trace dans le repo les déclarations de budget mémoire des wrappers persist/ de po-2024, passées de 12 Go à 42 Go après l'agrandissement de la VM WSL (24 032 → 40 110 Mo) arbitré par le user le 2026-09-21 (mission ai-01 msg-20260921T203652-qxg3en).

Pourquoi 42

COURSIA_RUNNER_BUDGET_GB est le plafond d'admission que assert_memory_budget (supervise.sh:439) compare à la somme des caps déclarés des conteneurs coursia-ci=1 de TOUTES les familles :

Jambe Slots Cap unitaire Caps déclarés
linux-docker 8 1536 Mo 12 288 Mo
waiters 12 1536 Mo 18 432 Mo
lean 2 6144 Mo 12 288 Mo
Total 22 43 008 Mo

Sous l'ancien budget 12 Go, la garde refusait des slots sains — les 2 slots lean ne démarraient jamais tant que les autres familles étaient en vol (18 432 + 12 288 > 12 288). Les vrais murs restent les caps par conteneur (docker --memory) et le plafond vmmem de la VM (memory=40GB) ; l'hôte garde sa moitié au-delà de la VM.

État live vs repo

  • Wrappers installés /usr/local/bin/coursia-{runner,lean}-start.sh : déjà à 42 sur la machine (mission du 2026-09-21).
  • Divergence live trouvée et corrigée dans le même geste : coursia-waiters-start.sh installé déclarait encore 12 pendant que runner/lean déclaraient 42 — exactement le défaut que les commentaires des wrappers nomment (« deux jambes qui divergeraient refuseraient leurs slots l'une contre l'autre »). Aligné à 42 en live (backup coursia-waiters-start.sh.bak-budget12), unité redémarrée active, flotte idle au moment du restart (0 conteneur en vol, coût nul).
  • Cette PR porte la déclaration dans le repo pour qu'elle reste auditable — la valeur effective vit dans un fichier que l'opérateur ouvre, pas dans un défaut de shell.

Hors scope (signalé, pas touché)

  • persist/coursia-waiters-start.sh est la copie de référence du déploiement ai-01 (préfixe myia-ai-01-linux-waiter) : aucune déclaration budget, VM de cette machine inconnue de cette lane — à ai-01 d'arbitrer la sienne.
  • Le wrapper waiters installé sur po-2024 n'a pas de copie de référence dans persist/ — la divergence live a été corrigée en ops ; une copie de référence po-2024 est un sujet séparé.

Validation

  • bash -n sur les deux fichiers modifiés : OK.
  • Grep BUDGET_GB dans persist/ : aucun test n'épingle la valeur 12 (test_sentinel_purge.sh ne couvre que la sentinelle).
  • Diff : 2 fichiers, commentaires + valeur uniquement (21 insertions, 11 deletions).

🤖 Generated with Claude Code

… la VM WSL 40 Go

Arbitrage user 2026-09-21 (mission ai-01 msg-20260921T203652-qxg3en) : la VM
WSL po-2024 passe de 24 032 a 40 110 Mo. Les declarations budget des wrappers
persist/ (runner + lean) suivent : 42 Go = somme des caps declares des trois
jambes (8x1536 docker + 12x1536 waiters + 2x6144 lean = 43 008 Mo). Sous
l'ancien 12 Go, les 2 slots lean etaient refuses tant que les autres familles
etaient en vol. Les wrappers installes /usr/local/bin/ sont deja a 42 sur la
machine (live fix, waiters aligne dans le meme geste) ; cette PR trace la
declaration dans le repo pour qu'elle reste auditable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the variation-adjacency-deep-med Adjacence DEEP/MED hors LIGHT : §2 l'autorise si substance distincte (coordinateur) label Sep 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Bash Syntax Advisory — shebang / executable-bit warnings

See the Shebang + dry-run advisory job log for the per-file ::warning:: lines. Non-blocking.

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Path-collision (organ #13359) — résolue

La collision de chemins signalée sur #17322 n'existe plus au passage du 2026-09-22T01:50Z : aucune autre PR ouverte ne partage désormais de chemin de fichier avec elle. Note laissée en place de l'avertissement (retraction non destructive).

@jsboige

jsboige commented Sep 22, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2026:CoursIA-3
pr: 17322
head: 30ab06f
complete: true
body: read
comments-reviewed: 2
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: 6188aac0c622a19eb0ac543a7edd8b89e1d0d0458eb96dab9994736cd3fdaee9
diff-files: 2
diff-additions: 21
diff-deletions: 11
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

@jsboige

jsboige commented Sep 22, 2026

Copy link
Copy Markdown
Owner Author

[INFO ripe-signal c.1395] PR #17322 narrow scope strict 1:1 ripe clean — ma lane myia-po-2024:CoursIA

Tell c.974 §G.9 strict fondateur vérif first-hand (REST API direct) :

  • narrow scope strict 1:1 ✓ (2 fichiers scripts CI runners : coursia-lean-start.sh + coursia-runner-start.sh, +21/-11 lignes)
  • MERGEABLE, 0 reviewers, 0 review formelle, 0 commentaire
  • HEAD branche : fix/runner-budget-declaration-40gb
  • Tell c.770 v3 ★★★★ vérif code COMPLET : mise à jour cohérente de constante 12 → 42 Go + commentaire narratif justifiant VM WSL 24 032 → 40 110 Mo (mission ai-01 msg-20260921T203652-qxg3en citée)
  • Tell c.A §A strict composite split obligatoire = OK (2 fichiers < 3000 lignes)
  • Tag LIGHT/tooling lane myia-po-2024:CoursIA

Tell c.594 strict respecté : worker ne merge pas (Tell c.1502 strict ×196ᵉ).
Tell c.14216 strict respecté : 0 auto-levee.
Tell c.15726 strict respecté : ripe-signal fondé sur vérif first-hand (pas spam, isolé vs batch c.1393).

Action attendue : ai-01 merge ou valide.

Rappel contexte c.1393 : 7 ripe-signaux fondés postés sur #16943 #16972 #16977 #16952 #16953 #16970 #16974 — toujours non mergés 60 min après.

@jsboige

jsboige commented Sep 22, 2026

Copy link
Copy Markdown
Owner Author

[ADJOINT PREFLIGHT]
schema: 1
lane: myia-po-2025:CoursIA-2
pr: 17322
head: 30ab06f
complete: true
body: read
comments-reviewed: 4
reviews-reviewed: 0
threads-reviewed: 0
threads-unresolved: 0
surfaces-sha256: faa0d8430dd01516db83ab90ebad99a8101d08cbd9505e59cc825768274c33de
diff-files: 2
diff-additions: 21
diff-deletions: 11
checks: latest-wins-green
b0: clear
scope: pass
domain: pass
verdict: READY
[/ADJOINT PREFLIGHT]

@myia-ai-01
myia-ai-01 merged commit 2d0414e into main Sep 22, 2026
19 of 20 checks passed
myia-ai-01 pushed a commit that referenced this pull request Oct 8, 2026
… mur kernel (#19802)

* fix(ci,#15091): budget memoire po-2024 coherent avec la VM de 24 Go + mur kernel

La VM WSL de po-2024 fait 24 032 Mo (.wslconfig memory=24GB, free -m), le
budget declare etait 42 Go (pose par #17322 pour une VM de 40 Go depuis
revenue a 24) et la composition reelle totalisait 27 648 Mo de caps
(6x1536 docker + 12x512 waiters + 2x6144 lean) -- une somme de caps
superieure a la RAM, payee en swap : 104 GiB ecrits en moins de 11 h,
DriveFS puis G: et RooSync emportes.

Budget 42 -> 21 (le meme sur les trois jambes), composition 21 504 Mo,
marge 2 528 Mo pour le noyau, dockerd et le page cache. On reduit des
NOMBRES DE SLOTS, jamais des CAPS : 3 des 6 conteneurs docker touchaient
leur cap de 1536 Mo a 99 %, c'est la concurrence qui ne tenait pas.

La machine n'avait aucun mur kernel (coursia-ci.slice inexistante,
MemoryHigh/Max/SwapMax = infinity) : le budget userspace refuse de
DEMARRER un slot, il ne borne pas ce qu'un slot deja lance consomme.
Ajout de persist/po-2024/coursia-ci.slice (MemoryHigh=20G, MemoryMax=22G,
MemorySwapMax=0) et de COURSIA_RUNNER_CGROUP_PARENT dans les deux
wrappers, qui y font entrer les conteneurs.

memory-swap = memory sur la jambe lean : consequence nommee dans le
fichier -- le build Hashlife de conway_lean depassait 16 Go a froid, il ne
passera plus a 6 Go sans swap, et la reponse est de le router vers un
runner hosted, pas de remonter le swap de cette machine.

Le drop-in waiters est scopé po-2024 : coursia-waiters.service est le
fichier d'ai-01 que les deux machines executent (byte-identique), editer
l'unite aurait descendu ai-01 en silence.

CPU 30 -> 24 : consequence arithmetique de la composition (4x3 + 2x6),
pas un arbitrage -- #15574 garde son point de retour J+7 du jour.

test_supervise_guards.sh : 137 PASS / 0 FAIL.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix: waiters wrapper probe les deux racines de depot connues

L'ancien defaut unique /mnt/d/CoursIA est correct pour ai-01 mais casse
po-2024 depuis la migration du 2026-09-17 (repo sous /mnt/d/Dev/CoursIA) :
au premier restart post-deploiement budget, la jambe waiters a crash-loope
sur 'master.env illisible' (StartLimitBurst epuise). Le wrapper etant
deploye a l'identique sur les deux sieges, le defaut sonde les deux racines
documentees (persist/README.md) ; surcharge COURSIA_REPO_DIR inchangee.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Fix(ci-runners): amendement J+7 po-2024 -- budget 15 Go, CPU 18 vCPU, lean 2->1, slice 14/16G

Point de retour prevu par l'arbitrage #15574 item 3, joue le 2026-10-08 :
characterize_runner_variance.py --days 7 (456 jobs lourds) mesure le ratio
p90/mediane a 9,3/5,1/14,5/4,0/23,3/15,4 par runner po-2024 -- 5 runners
sur 6 au-dessus du seuil 5x. La regle s'applique : CPU 24 -> 18
(docker 4x3 + lean 1x6), right-sizing lean 2 -> 1 slots (cap unitaire
6 Go / 6 vCPU INCHANGE, volume chaud lean-2 conserve).

La memoire suit : budget 21 -> 15 (composition 4x1536 + 6x512 + 1x6144
= 15 360 Mo, marge 8 672 Mo sur 24 032), slice po-2024 MemoryHigh 14G /
MemoryMax 16G. Commentaires des huit fichiers persist/ realignes (le
point de retour J+7 passe d'ouvert a resolu, references croisees 20G/22G
corrigees).

Temoins : test_supervise_guards.sh rejoue sur le worktree -- 137 PASS /
0 FAIL. Deploiement a suivre (fichiers vivants encore a 21/24/2 slots).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
myia-ai-01 pushed a commit that referenced this pull request Oct 9, 2026
… VM (#19851)

* feat(infra,#19805): assert_memory_budget -- organe composition vs RAM VM

Issue #19805 -- fix(runners): budget memoire po-2024 incoherent avec la VM
(42 Go declares pour 24 032 Mo disponibles). Le budget cumule des conteneurs
runners (effectifs x caps) etait superieur a la RAM de la VM WSL, et rien
dans l'instrumentation existante ne le detectait. measure_po2024_topology
mesure la topologie OS mais ne confronte pas la composition au budget declare,
et le garde precedent ne connaissait que le budget (pas la RAM VM). Cause
racine documentee : agrandissement VM 2026-09-24 revertu, declarations non
revisees (deuxieme derive de la meme famille, la premiere corrigee par #17322
dans l'autre sens).

Livrable :
- scripts/ci/assert_memory_budget.py : organe cross-platform qui lit la RAM
  VM via measure_po2024_topology.measure() et la composition depuis
  docker-configurations/runners/<host>_budget.json (snapshot canonique),
  confronte a la borne la plus contraignante (min entre MemoryMax de la
  slice et RAM VM - hote reserve 0.5 GiB). Sortie texte ou --json. Exit 0
  si composition <= borne, 1 sinon.
- docker-configurations/runners/po2024_budget.json : snapshot de la
  composition mesuree firsthand (docker 6x1.5=9, waiters 12x0.5=6, lean
  2x6=12 = 27.0 GiB). Verdict au snapshot : INCOHERENT (27.0 > 16.0
  MemoryMax slice).
- scripts/tests/test_assert_memory_budget.py : 10 tests unitaires
  (load snapshot, parse MemoryMax, OK/INCOHERENT, marge, snapshot bien
  forme). 10/10 verts en local.
- .github/workflows/assert-memory-budget.yml : CI bloquante sur PR/push
  touchant le snapshot, l'organe, la topologie, la slice ou supervise.sh.
  Schedule lundi 06:37 UTC pour detecter la derive de l'instrument quand
  aucune PR ne touche le snapshot. Run sur ubuntu-latest (jamais
  self-hosted : l'observateur ne doit pas consommer ce qu'il observe).

Anti-patterns evites :
- Re-implémenter measure_po2024_topology : refus. L'organe importe la
  fonction measure() deja existante (cf. #13564 organ-first).
- Mesure VM dependante du daemon docker : refus. measure() lit la RAM
  via WMI / procfs / sysctl sans docker.
- Hand-edit sortie : refus (secrets-hygiene regle 6).
- Rapport commité : refus (cadrage coordinateur 07/10 + CLAUDE.md §A).

Scope CPU strict -- pas d'execution CI sur la machine cible (po-2024) :
le workflow tourne sur ubuntu-latest pour verifier l'instrument, et un
operateur execute l'organe sur po-2024 elle-meme (le snapshot detecte
l'incoherence via la slice 16 GiB, qui est partagee par toutes les machines
CI). Le gate est : composition <= borne tranche au plus serré.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>

* fix(infra,#19851): assert_memory_budget -- 3 defauts revue coordinateur (composition derivee, surcharge slice, RAM VM declaree)

Revue coordinateur 2026-10-08 (commentaire 🟡 cid 6053027290) a identifie 3
defauts sur l'organe #19805 :

1. Composition maintenue a la main (po2024_budget.json) -> derive depuis
   supervise.sh (BudgetSnapshot.from_supervise_defaults). Le snapshot JSON
   derive a chaque push supervise.sh, l'organe mesurait alors son propre
   instantane au lieu du deploiement. Lecture directe des variables
   COURSIA_RUNNER_MEMORY / COURSIA_RUNNER_WAITER_MEMORY /
   COURSIA_LEAN_RUNNER_MEMORY + N par defaut (2 start / 24 waiters / 2 lean).

2. Slice generique persist/coursia-ci.slice (16G) surchargeait la lecture
   sans tenir compte d'un plafond machine-specifique. Ajout lookup_slice()
   qui cherche persist/<machine>/coursia-ci.slice d'abord, fallback
   generique. La surcharge po-2024 n'est pas encore materialisee (#19802)
   mais le motif est en place.

3. RAM VM mesuree sur l'hote de l'organe (191.8 GiB ai-01, 63.6 GiB po-2027)
   au lieu d'etre declaree (24 GiB po-2024). Defaut fondateur ferme :
   l'organe peut tourner depuis n'importe quelle machine du cluster, mais
   c'est la machine-CIBLE qui plafonne. Constante PO2024_VM_RAM_GIB=24.0
   + lookup_vm_ram_gib() + avertissement stderr si machine inconnue
   (mode slice seule).

Tests : 16/16 verts (10 anciens + 6 nouveaux : lookup_vm_ram_gib x2,
lookup_slice x2, from_supervise_defaults x2). Le mode JSON snapshot reste
l'option par defaut pour la compat ascendante ; --from-supervise est opt-in
(derive depuis supervise.sh defauts).

Validation manuelle :
  python scripts/ci/assert_memory_budget.py --from-supervise --machine po-2024
  [INCOHERENT] po-2024 : composition 27.0 GiB vs borne 16.0 GiB
    start :   2 x   1.5 GiB =    3.0 GiB
    waiters :  24 x   0.5 GiB =   12.0 GiB
    lean :   2 x   6.0 GiB =   12.0 GiB
    TOTAL :                  27.0 GiB
    VM RAM        :   24.0 GiB  (hote reserve 0.5 GiB)
    Slice MemoryMax:   16.0 GiB
    Borne         :   16.0 GiB  (marge 0.5 GiB, seuil 15.5 GiB)

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>

* fix(infra,#19851): composition derivee des unites deployees, pas de l'instantane

Defaut 1 de la revue coordinateur, resté ouvert : le defaut de la composition
etait encore le snapshot JSON recopie a la main. La CI appelle l'organe sans
drapeau, donc il remesurait sa propre constante. La derivation
`from_supervise_defaults` (valeurs documentees en en-tete de `supervise.sh`)
derivait elle aussi du deploiement : 24 slots d'attente documentes quand
l'unite en lance 12, et 6 sur po-2024 par drop-in.

- `from_deployed_units(machine)` : effectif = dernier jeton entier de
  l'`ExecStart` du wrapper de jambe, cap = `Environment=` de la meme unite ;
  le drop-in `persist/<machine>/<unite>.d/*.conf` surcharge l'unite de base.
- Composition par defaut = unites deployees. `--from-json` et
  `--from-supervise` restent disponibles pour l'audit et le repli.
- Provenance portee au verdict (champ `source`, texte et JSON) : un organe qui
  confronte une composition dit d'ou elle vient.
- Workflow : les `paths:` couvrent `persist/**` -- sans quoi le guard ne se
  relance pas quand un dimensionnement change, et rend un verdict perime.
- Test stale corrige : `lookup_slice` sur po-2024 affirmait le repli sur la
  generique en se fondant sur l'absence de la surcharge, materialisee depuis
  #19802. Le postulat avait disparu avec le deploiement.

Mesure : la composition reelle de `main` (4 x 1.5 + 6 x 0.5 + 1 x 6 = 15.0 GiB)
tient sous le seuil 15.5 GiB. Le rouge `Composition vs RAM VM` etait un
artefact de lecture, pas une incoherence du deploiement -- c'est la reponse que
la revue demandait a l'organe.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>

* fix(ci,#19851): installer pytest dans le smoke test du workflow

Le runner ubuntu-latest n'expose pas pytest dans le Python 3.13 installe par
setup-python : l'etape `Run pytest (smoke)` echouait sur `No module named
pytest` (rouge fondeur du 2026-10-09), pas sur le code de l'organe. Ajout
d'une etape d'installation explicite avant le smoke test.

Co-Authored-By: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

variation-adjacency-deep-med Adjacence DEEP/MED hors LIGHT : §2 l'autorise si substance distincte (coordinateur)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants